package br.unifor.cct.mia.mutation;

import java.util.List;

import br.unifor.cct.mia.dataenhancement.Attribute;
import br.unifor.cct.mia.dataenhancement.Structure;
import br.unifor.cct.mia.evolutionary.FeatureConstructionGenotype;
import br.unifor.cct.mia.ga.Ga;
import br.unifor.cct.mia.ga.util.FeatureConstructionGene;
import br.unifor.cct.mia.util.Methods;

public class FeatureConstructionMutation implements Mutation {

	private void mutate(Ga Ga, Structure struc) {
		double x;

		for (int i = 0; i < Ga.configurations.getPopsize(); i++) {

			x = Methods.randDoubleValue(0, 1);

			if (x*100 < Ga.configurations.getPmutation()*100) {				 
				
					int j = Methods.randIntValue(0, Ga.configurations.getNvars()-1);

					int type = Methods.randIntValue(0, 1);
					FeatureConstructionGenotype indiv = (FeatureConstructionGenotype) Ga.population[i];
					FeatureConstructionGene gen = indiv.getGene()[j];

					if (type == 0) { //Troca apenas o bit                		
						if (gen.getActiveBit() == 0) {
							gen.setActiveBit((byte) 1);
						} else {
							gen.setActiveBit((byte) 0);
						}
					} else { //Troca o valor do atributo
						int pos = -1;
						for (int z = 0; z < struc.size(); z++) {
							Attribute att = struc.getAttribute(z);
							if (att.getName().equalsIgnoreCase(
									gen.getAttribute())) {
								pos = z;
								break;
							}
						}
						if (pos != -1) {
							List values = struc.getValues(pos);
							int vlPos = Methods.randIntValue(0,
									values.size() - 1);

							gen.setValue( String.valueOf( values.toArray()[vlPos] ) );
						}
					}

					Methods.verificarMinActive(indiv.getGene());
				
			}

		}
	}
	
	public Object execute(Object value) {
		Object[] o = (Object[])value;
		Structure struc = (Structure)o[0];
		Ga Ga = (Ga)o[1];
		
        mutate(Ga,struc);        
		return Ga.population;
	}

}
